package com.google.code.bankagregator.dao;

import com.google.code.bankagregator.entities.Credit;
import com.google.code.bankagregator.entities.State;

import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Credit CrudDAO class
 * User: kaiser
 */
@Stateless
public class CreditDAO extends DAO {

    private final Logger log = Logger.getLogger(DepositDAO.class.getName());

    public void update(Credit entity) {
        try {
            Credit deposit = getCreditId(entity);
            entity.setId(deposit.getId());
        } catch (NoResultException ex) {
            log.log(Level.INFO, "New credit entity " + entity.toString());
        }
        entity.setAdded(new Date());
        getEntityManager().merge(entity);
    }

    /**
     * Search for ID for data from parser
     *
     * @param entity form parser
     * @return value object
     */
    public Credit getCreditId(Credit entity) {
        Query query = getEntityManager()
                .createQuery("SELECT c FROM Credit c WHERE " +
                        "c.name = :name AND " +
                        "c.url = :url AND " +
                        "c.state = :state AND " +
                        "c.currency = :currency AND " +
                        "c.maxAmount = :maxAmount AND " +
                        "c.minAmount = :minAmount AND " +
                        "c.term = :term AND " +
                        "c.prepayment = :prepayment AND " +
                        "c.type = :ctype ");

        query.setParameter("name", entity.getName());
        query.setParameter("url", entity.getUrl());
        query.setParameter("state", entity.getState());
        query.setParameter("currency", entity.getCurrency());
        query.setParameter("maxAmount", entity.getMaxAmount());
        query.setParameter("minAmount", entity.getMinAmount());
        query.setParameter("term", entity.getTerm());
        query.setParameter("prepayment", entity.getPrepayment());
        query.setParameter("ctype", entity.getType());

        return (Credit) query.getSingleResult();
    }

    public void delete(Credit entity) {
        Credit deletedApplicant = entity;
        if (!getEntityManager().contains(entity)) {
            deletedApplicant = getEntityManager().merge(entity);
        }

        getEntityManager().remove(deletedApplicant);
    }

    public void delete(int id) {
        Credit credit = getById(id);
        delete(credit);
    }

    public void create(Credit entity) {
        getEntityManager().persist(entity);
    }

    public Credit getById(int id) {
        return getEntityManager().find(Credit.class, id);
    }

    public List<Credit> getAll() {
        return getEntityManager().createQuery("SELECT c FROM Credit c").getResultList();
    }

    /**
     * get List of credits by type and currency criteria
     *
     * @param criteria
     * @return
     */
    public List<Credit> getByCriteria(Credit criteria) {

        Query query = getEntityManager()
                .createQuery("SELECT c FROM Credit c WHERE " +
                        "c.type = :type AND " +
                        "c.currency = :currency AND " +
                        "c.minAmount <= :amount AND " +
                        "(c.prepayment <= :prepayment OR :prepayment = 0 )  AND" +
                        "(c.maxAmount = 0 OR c.maxAmount >= :amount) AND " +
                        "(c.term = 0 OR c.term >= :term)"
                );

        query.setParameter("type", criteria.getType());
        query.setParameter("currency", criteria.getCurrency());
        query.setParameter("amount", criteria.getMaxAmount());
        query.setParameter("prepayment", criteria.getPrepayment());
        query.setParameter("term", criteria.getTerm());

        return query.getResultList();
    }

    /**
     * Return list not archived credits
     *
     * @return
     */
    public List<Credit> getActive() {
        Query query = getEntityManager()
                .createQuery("SELECT c FROM Credit c WHERE " +
                        "c.state <> :archive ");

        query.setParameter("archive", State.ARCHIVE);

        return query.getResultList();
    }


}
